package com.beiding.sqlbuilder.impl;

import com.beiding.sqlbuilder.*;

import java.util.List;

public class SimpleQueryBuilder implements QueryBuilder {

    private ConditionUnitContainer conditionUnitContainer;

    private BuilderContext builderContext;

    @Override
    public void setContext(BuilderContext context) {
        this.builderContext = context;
    }


    @Override
    public BuilderContext getContext() {
        return builderContext;
    }

    private Tables tables = new Tables();

    SimpleQueryBuilder() {

    }

    void setConditionUnitContainer(ConditionUnitContainer conditionUnitContainer) {
        this.conditionUnitContainer = conditionUnitContainer;
    }

    ConditionUnitContainer getConditionUnitContainer() {
        return conditionUnitContainer;
    }

    public interface InnerQ {
        void inner(SimpleQueryBuilder q);
    }

    public interface InnerE {
        void inner(SimpleExpressionBuilder e);
    }

    public SimpleQueryBuilder expression(InnerE innerE) {
        SimpleExpressionBuilder e = new SimpleExpressionBuilder();
        SimpleConditionUnitContainer simpleConditionUnitContainer = new SimpleConditionUnitContainer();
        e.setConditionUnitContainer(simpleConditionUnitContainer);
        innerE.inner(e);
        conditionUnitContainer.addConditionUnit(simpleConditionUnitContainer);
        List<Table> tables = e.getTables();
        this.tables.addTables(tables);
        return this;
    }

    //算式构建器
    public SimpleQueryBuilder eq(Object a, Object b) {
        conditionUnitContainer.addConditionUnit(new SimpleCompareUnit(CompareType.Eq, ConditionUtils.createParameters(tables, a, b)));

        return this;
    }

    public SimpleQueryBuilder in(Object a, Object b) {
        conditionUnitContainer.addConditionUnit(new SimpleCompareUnit(CompareType.In, ConditionUtils.createParameters(tables, a, b)));
        return this;
    }

    public SimpleQueryBuilder in(Object a, Object... bs) {
        return in(a, (Object) bs);
    }

    public SimpleQueryBuilder and() {
        conditionUnitContainer.addConditionUnit(new SimpleLogicConnector(LogicType.And));
        return this;
    }

    public SimpleQueryBuilder or() {
        conditionUnitContainer.addConditionUnit(new SimpleLogicConnector(LogicType.Or));
        return this;
    }

    public SimpleQueryBuilder and(InnerQ innerQ) {
        SimpleQueryBuilder q = new SimpleQueryBuilder();
        q.conditionUnitContainer = new SimpleConnectorConditionUnitContainer(LogicType.And);
        innerQ.inner(q);
        conditionUnitContainer.addConditionUnit(q.conditionUnitContainer);
        return this;
    }

    public SimpleQueryBuilder or(InnerQ innerQ) {
        SimpleQueryBuilder q = new SimpleQueryBuilder();
        q.conditionUnitContainer = new SimpleConnectorConditionUnitContainer(LogicType.Or);
        innerQ.inner(q);
        conditionUnitContainer.addConditionUnit(q.conditionUnitContainer);
        return this;
    }


    @Override
    public String build() {
        conditionUnitContainer.build(builderContext);
        ConditionUnitHolder conditionUnitHolder = ConditionUtils.buildConditionUnitHolder(conditionUnitContainer, builderContext.getConditionUnitHandlers());
        return conditionUnitHolder.execute();
    }

    @Override
    public List<Table> getTables() {
        return tables.getTables();
    }


}
